<template>
  <div>
    <button @click="tips">提示信息</button>
    <div class="monaco-wrapper" style="text-align: left" ref="container"></div>
    <!--宽高自行设定 -->
  </div>
</template>

<script>
import * as monaco from "monaco-editor";
import "monaco-editor/esm/vs/basic-languages/sql/sql.contribution";
import "monaco-editor/esm/vs/editor/contrib/find/findController";

export default {
  data() {
    return {
      hints: [],
    };
  },
  watch: {
    hints(newV) {
      if (newV) {
        // this.editor.trigger('提示', 'editor.action.triggerSuggest', {});
      }
    },
  },
  methods: {
    tips() {
      this.editor.trigger("随便写点儿啥", "editor.action.triggerSuggest", {});
    },
  },
  mounted() {
    // 初始化编辑器，确保dom已经渲染
    this.editor = monaco.editor.create(this.$refs["container"], {
      value: "dfdsddgertwetrwetr", //编辑器初始显示文字
      language: "sql", //语言支持自行查阅demo
      automaticLayout: true, //自动布局
      theme: "vs-dark", //官方自带三种主题vs, hc-black, or vs-dark,
      selectOnLineNumbers: true, //显示行号
      roundedSelection: false,
      readOnly: false, // 只读
      cursorStyle: "line", //光标样式
      glyphMargin: true, // 字形边缘
      useTabStops: false,
      // fontSize: 28,       //字体大小
      autoIndent: true, //自动布局
      quickSuggestionsDelay: 500, //代码提示延时
    });

    //提示项设值
    monaco.languages.registerCompletionItemProvider("sql", {
      provideCompletionItems: function (model, position) {
        // 获取当前行数
        const line = position.lineNumber;

        // 获取当前列数
        const column = position.column;
        // 获取当前输入行的所有内容
        const content = model.getLineContent(line);
        console.log("", content);
        // 通过下标来获取当前光标后一个内容，即为刚输入的内容
        const sym = content[column - 2];
        // var textUntilPosition = model.getValueInRange({
        //   startLineNumber: 1,
        //   startColumn: 1,
        //   endLineNumber: position.lineNumber,
        //   endColumn: position.column,
        // });
        var word = model.getWordUntilPosition(position);
        var range = {
          startLineNumber: position.lineNumber,
          endLineNumber: position.lineNumber,
          startColumn: word.startColumn,
          endColumn: word.endColumn,
        };
        //---------------------------------------------------
        //上面的代码仅仅是为了获取sym，即提示符
        //---------------------------------------------------
        var suggestions = [];
        if (sym == "$") {
          console.log(sym);
          //...
          //拦截到用户输入$，开始设置提示内容，同else中代码一致，自行拓展
          suggestions.push({
            label: "这是自定义提示内容", // 显示的提示内容
            kind: monaco.languages.CompletionItemKind["Function"], // 用来显示提示内容后的不同的图标
            insertText: "这是自定义提示要插入的内容：insertText", // 选择后粘贴到编辑器中的文字
            detail: "", // 提示内容后的说明
            range: range,
          });
        } else if (content.length > 1 && content.slice(-2).slice(0, 1) == " ") {
          suggestions.push({
            label: "aaaaa", // 显示的提示内容
            kind: monaco.languages.CompletionItemKind["Function"], // 用来显示提示内容后的不同的图标
            insertText: "aaaaa", // 选择后粘贴到编辑器中的文字
            detail: "", // 提示内容后的说明
            range: range,
          });
        } else {
          //直接提示，以下为sql语句关键词提示
          var sqlStr = [
            "SELECT",
            "FROM",
            "WHERE",
            "AND",
            "OR",
            "LIMIT",
            "ORDER BY",
            "GROUP BY",
          ];
          for (var i in sqlStr) {
            suggestions.push({
              label: sqlStr[i], // 显示的提示内容
              kind: monaco.languages.CompletionItemKind["Function"], // 用来显示提示内容后的不同的图标
              insertText: sqlStr[i], // 选择后粘贴到编辑器中的文字
              detail: "", // 提示内容后的说明
              range: range,
            });
          }

          // mock start
          let le = "abcdefghijklmnopqrstuvwxyz";
          new Array(1000).fill(9999).forEach(() => {
            let a = le[Math.round(Math.random() * 10)],
              b = le[Math.round(Math.random() * 10)],
              c = le[Math.round(Math.random() * 10)];

            let rd = a + b + c + Math.random();
            suggestions.push({
              label: rd, // 显示的提示内容
              kind: monaco.languages.CompletionItemKind["Function"], // 用来显示提示内容后的不同的图标
              insertText: rd, // 选择后粘贴到编辑器中的文字
              detail: "", // 提示内容后的说明
              range: range,
            });
          });

          suggestions.push({
            label: "Free Storage Method", // 显示的提示内容
            kind: monaco.languages.CompletionItemKind["Function"], // 用来显示提示内容后的不同的图标
            insertText: "Free Storage Method", // 选择后粘贴到编辑器中的文字
            detail: "", // 提示内容后的说明
            range: range,
          });

          // mock end
        }
        return {
          suggestions: suggestions,
        };
      },
      triggerCharacters: ["$", ""],
    });

    //监听变化
    /* this.editor.onDidChangeModelContent(e => {
        this.caretOffset = e.changes[0].rangeOffset;//获取光标位置
        this.value= this.editor.getValue(); //使value和其值保持一致
    }) */
  },
  beforeDestroy() {
    this.editor.dispose(); // 使用完后销毁
  },
};
</script>


<style scoped>
.monaco-wrapper {
  width: auto;
  height: 800px;
  text-align: left !important;
  border: 1px solid #ccc;
}
</style>